//------------------------------------------------------------------------------
#include <QImage>
#include <QPrinter>
#include <QPainter>
#include <QtGui>
#include <QFileDialog>
#include <QPrintDialog>
#include <QByteArray>
#include "CPrintPreviewFrm.h"
#include "CMimeType.h"
#include "CTomcatClient.h"
//------------------------------------------------------------------------------
CPrintPreviewFrm *CPrintPreviewFrm::instance=NULL;
//------------------------------------------------------------------------------
CPrintPreviewFrm * CPrintPreviewFrm::getInstance(void) {
	if(instance == NULL) {
		instance=new CPrintPreviewFrm();
	}
	return instance;
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::print(CRequest *request, EPrintType printType, QWidget *parent) {
	_printType=printType;
	_parent=parent;
	
	_parent->setCursor(Qt::WaitCursor);
	CTomcatClient tomcatClient;
	
	if(tomcatClient.report(request, datas, contentType)) {
		switch(_printType) {
			default:
			case eptScreen: 
				toScreen();
				break;
			case eptPrinter:
				toPrinter();
				break;
			case eptFile:
				toFile();
				break;
		}
	}else {
		QMessageBox msgBox(	QMessageBox::Critical , tr("Erreur"), 
							tomcatClient.getLastError(), QMessageBox::Ok);
		
		msgBox.exec();
	}
}
//------------------------------------------------------------------------------
CPrintPreviewFrm::CPrintPreviewFrm() : QDialog(0, Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint) {
	setupUi(this);
	
	pdfRender=new QLabel(this);
	pdfRender->setBackgroundRole(QPalette::Base);
	pdfRender->setAlignment(Qt::AlignCenter);
	pdfRender->setStyleSheet("border: 1px solid black");
	
	scrollArea->setWidget(pdfRender);
	scrollArea->setBackgroundRole(QPalette::Dark);
	
	doc=NULL;
	nbPage=currentPage=0;
	
	cbZoom->addItem("25%", QVariant(0.25));
	cbZoom->addItem("50%", QVariant(0.5));
	cbZoom->addItem("75%", QVariant(0.75));
	cbZoom->addItem("100%", QVariant(1));
	cbZoom->addItem("150%", QVariant(1.5));
	cbZoom->addItem("200%", QVariant(2));
	cbZoom->addItem("300%", QVariant(3));
	
	cbZoom->setCurrentIndex(1);
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::toScreen(void) {
	if(contentType == "application/pdf") {
		doc=Poppler::Document::loadFromData(datas);
		if(doc == 0) {
			QMessageBox msgBox(	QMessageBox::Critical , tr("Attention"), 
								tr("Erreur lors de la génération de l'impression"), QMessageBox::Ok);
			
			msgBox.exec();
			return;
		}
		
		doc->setRenderHint((Poppler::Document::RenderHint)3);
		
		nbPage=doc->numPages();
		leTo->setText(QString::number(nbPage));
		
		renderPage(0);

		exec();
		
		datas.clear();
		delete doc;
	}else {
		QMessageBox msgBox(	QMessageBox::Critical , tr("Attention"), 
							tr("Le type de fichier ")+contentType+tr(" n'est pas pris en charge"), QMessageBox::Ok);
							
		msgBox.exec();
	}
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::toPrinter(void)
{
	doc=Poppler::Document::loadFromData(datas);
	if(doc == 0) {
		QMessageBox msgBox(	QMessageBox::Critical , tr("Attention"), 
							tr("Erreur lors de la génération de l'impression"), QMessageBox::Ok);
		
		msgBox.exec();
		return;
	}
	
	doc->setRenderHint((Poppler::Document::RenderHint)3);
	
	on_printDocument_clicked();
	
	datas.clear();
	delete doc;
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::toFile(void) {
	QFile *file;
	QDataStream *dataStream;
	QList<QString> exts=CMimeType::getInstance()->getExtensions(contentType);
	QString filter="", s="";
	
	for(int i=0;i<exts.size();i++) {
		filter+=s+"Fichiers "+exts.at(i)+"(*."+exts.at(i)+")";
		s=";;";
	}
	
	QString fileName=QFileDialog::getSaveFileName(_parent, tr("Enregistrer sous"), "", filter);
	
	if(fileName != "") {
		file=new QFile(fileName);
		if(file->open(QIODevice::WriteOnly | QIODevice::Truncate)) {
			dataStream=new QDataStream(file);
			
			dataStream->writeRawData(datas.data(), datas.count());
			
			delete dataStream;
			delete file;
		}
	}
	
	datas.clear();
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::renderPage(int pageNum) {
	if(doc != NULL) {
		double scaleFactor=cbZoom->itemData(cbZoom->currentIndex()).toDouble();
		Poppler::Page *pdfPage=doc->page(pageNum);
		if(pdfPage != NULL) {
			QImage img=pdfPage->renderToImage(scaleFactor*pdfRender->physicalDpiX(), scaleFactor*pdfRender->physicalDpiY());
				
			pdfRender->setPixmap(QPixmap::fromImage(img));
			
			currentPage=pageNum;
			leFrom->setText(QString::number(currentPage+1));
			
			pageSuivante->setEnabled(currentPage < nbPage-1);
			pagePrecedente->setEnabled(currentPage > 0);
		}
	}
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::on_premierePage_clicked(void) {
	renderPage(0);
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::on_pagePrecedente_clicked(void) {
	if(currentPage > 0) {
		renderPage(currentPage-1);
	}
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::on_pageSuivante_clicked(void) {
	if(currentPage < nbPage-1) {
		renderPage(currentPage+1);
	}
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::on_dernierePage_clicked(void) {
	renderPage(nbPage-1);
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::on_cbZoom_currentIndexChanged(int index) {
	renderPage(currentPage);
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::on_printDocument_clicked(void) {	
	QPrintDialog *printDialog=new QPrintDialog(this);
	if(printDialog->exec() == QDialog::Accepted) {
		QPrinter *printer=printDialog->printer();
		printer->setPageMargins(0, 0, 0, 0, QPrinter::Point);
		printer->setResolution(150);
		
		int printerResolution = printer->resolution();

		int paperWitdh = printer->paperRect(QPrinter::DevicePixel).width();
		int paperHeight = printer->paperRect(QPrinter::DevicePixel).height();

		int pageWidth = printer->pageRect(QPrinter::DevicePixel).width();
		int pageHeight = printer->pageRect(QPrinter::DevicePixel).height();
		QPainter p;
		p.begin(printer);
		p.setRenderHint((QPainter::RenderHint)0, true);
		
		int f=printer->fromPage();
		int t=printer->toPage();
		int nbPageToPrint;
		int sens=1;
		int i,j;
		
		switch(printer->printRange()) {
			default:
			case QPrinter::AllPages:
				f=0;
				t=doc->numPages();
				break;
			case QPrinter::PageRange:
				f--;
				break;
		}
		
		nbPageToPrint=t*printer->numCopies();
		
		if(printer->pageOrder() == QPrinter::LastPageFirst) {
			qSwap(f, t);
			f--;
			t--;
			sens=-1;
		}
		
		for(i=1,j=f;i<=nbPageToPrint;i++) {
			Poppler::Page *pdfPage=doc->page(j);
			QImage printImage = pdfPage->renderToImage(printerResolution, printerResolution, 0, 0, paperWitdh, paperHeight);
			p.drawImage(QRect(0, 0, pageWidth, pageHeight), printImage);
				
			if(i<nbPageToPrint) {
				printer->newPage();
			}
			
			if(printer->collateCopies()) {
				j+=sens*(i%printer->numCopies() == 0 ? 1 : 0);
			}else {
				j+=sens;
				if(j == t)
				{
					j=f;
				}
			}
		}
		p.end();
	}
	
	delete printDialog;
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::on_leFrom_textEdited(const QString &text) {
	bool ok;
	int pageNum=text.toInt(&ok);
	
	if(ok) {
		if(pageNum > 0 && pageNum <= nbPage) {
			renderPage(pageNum-1);
			return;
		}
	}
	leFrom->setText(QString::number(currentPage+1));
}
//------------------------------------------------------------------------------
void CPrintPreviewFrm::on_printToFile_clicked(void) {
	toFile();
	accept();
}
//------------------------------------------------------------------------------

